Skip to content

Add ProjectLatest API to project aggregates with pending events#4252

Merged
jeremydmiller merged 1 commit intomasterfrom
feature/4249-project-pending-events
Apr 14, 2026
Merged

Add ProjectLatest API to project aggregates with pending events#4252
jeremydmiller merged 1 commit intomasterfrom
feature/4249-project-pending-events

Conversation

@jeremydmiller
Copy link
Copy Markdown
Member

Summary

Closes #4249

Adds session.Events.ProjectLatest<T>(id) — a new API that returns the projected aggregate state including any events appended in the current session but not yet committed via SaveChangesAsync().

Before (forced flush + re-read):

session.Events.StartStream<Report>(id, new ReportCreated("Q1"));
await session.SaveChangesAsync(ct);  // forced flush
var report = await session.Events.FetchLatest<Report>(id, ct);  // re-read

After (project locally):

session.Events.StartStream<Report>(id, new ReportCreated("Q1"));
var report = await session.Events.ProjectLatest<Report>(id, ct);
// SaveChangesAsync happens later

Behavior by projection lifecycle:

  • Live: fetches committed events from DB, builds aggregate, then applies pending events on top
  • Inline: loads pre-projected document, applies pending events, stores updated document in session for persistence on SaveChangesAsync()
  • Async: same as inline
  • Natural key: falls back to FetchLatest (pending events use stream IDs, not natural keys)

Test plan

  • Live projection: pending events from StartStream are included
  • Inline projection: pending events are included
  • Inline projection: updated document is stored and persisted on SaveChangesAsync
  • No pending events: behaves like FetchLatest
  • Live projection: committed + pending events combined
  • Nonexistent stream returns null

🤖 Generated with Claude Code

Adds session.Events.ProjectLatest<T>(id) which returns the projected
aggregate state including uncommitted events from the current session.
For inline projections, the updated document is also stored in the
session so it persists on SaveChangesAsync.

This eliminates the forced SaveChangesAsync + FetchLatest round-trip
pattern in command handlers that need the projected state immediately
after appending events.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jeremydmiller jeremydmiller force-pushed the feature/4249-project-pending-events branch from 2637880 to 185254b Compare April 14, 2026 23:30
@jeremydmiller jeremydmiller merged commit 54ea9ee into master Apr 14, 2026
6 checks passed
@jeremydmiller jeremydmiller deleted the feature/4249-project-pending-events branch April 14, 2026 23:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Advance a single stream projection to the latest pending version including in-flight events

1 participant